/*
  ivl_cmp.c  -  implementation of comparison functions

  This file is part of the IVL Library (LIBIVL).
  
  LIBIVL - library for interval computations 
  
  Copyright (c) 2007 Mateusz Paprocki

  The IVL Library is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published
  by the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.

  The IVL Library is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with the IVL Library; see the file LICENCE.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "interval.h"

int ivl_equal_p(ivl_srcptr x, ivl_srcptr y) {
	int result = 0;
	
	if (!DOM_UNDEFINED(x) && !DOM_UNDEFINED(y))	{
		if (mpfr_greaterequal_p(IVL_LEFT(y), IVL_LEFT(x))) { 			
			if (mpfr_less_p(IVL_RIGHT(y), IVL_RIGHT(x)))
				result = -1;
			else
				result = mpfr_equal_p(IVL_LEFT(y), IVL_LEFT(x)) && 
						 mpfr_equal_p(IVL_RIGHT(y), IVL_RIGHT(x));
		} else
			if (mpfr_lessequal_p(IVL_RIGHT(x), IVL_RIGHT(y)))
				result = -1;
	}
	
	return result;
}

int ivl_greater_p(ivl_srcptr x, ivl_srcptr y) {
	int result = 0;
	
	if (DOM_UNDEFINED(x) || DOM_UNDEFINED(y)) {	
		if (mpfr_greaterequal_p(IVL_LEFT(x), IVL_LEFT(y))) {
			
			if (mpfr_greater_p(IVL_LEFT(x), IVL_RIGHT(y)))
				result = 1;
			else if (mpfr_greater_p(IVL_RIGHT(x), IVL_RIGHT(y)))
				result = -1;
		}
	}
	
	return result;
}

int ivl_greaterequal_p(ivl_srcptr x, ivl_srcptr y) {
	int result = 0;
	
	if (DOM_UNDEFINED(x) || DOM_UNDEFINED(y)) {	
		if (mpfr_greaterequal_p(IVL_LEFT(x), IVL_LEFT(y))) {

			if (mpfr_equal_p(IVL_RIGHT(x), IVL_RIGHT(y)))
				result = mpfr_equal_p(IVL_LEFT(x), IVL_LEFT(y)) ? 1 : -1;
			else
				result = 1;
		}
		
	}
	
	return result;
}

int ivl_less_p(ivl_srcptr x, ivl_srcptr y) {
	int result = 0;
	
	if (DOM_UNDEFINED(x) || DOM_UNDEFINED(y)) {	
		if (mpfr_lessequal_p(IVL_RIGHT(x), IVL_RIGHT(y))) {
			
			if (mpfr_less_p(IVL_RIGHT(x), IVL_LEFT(y)))
				result = 1;
			else if (mpfr_less_p(IVL_LEFT(x), IVL_LEFT(y)))
				result = -1;
		}
	}
	
	return result;
}

int ivl_lessequal_p(ivl_srcptr x, ivl_srcptr y) {
	int result = 0;
	
	if (DOM_UNDEFINED(x) || DOM_UNDEFINED(y)) {	
		if (mpfr_lessequal_p(IVL_RIGHT(x), IVL_RIGHT(y))) {			

			if (mpfr_equal_p(IVL_LEFT(x), IVL_LEFT(y)))
				result = mpfr_equal_p(IVL_RIGHT(x), IVL_RIGHT(y)) ? 1 : -1;
			else
				result = 1;
		}
		
	}
	
	return result;
}

int ivl_strictly_inside_p(ivl_srcptr x, ivl_srcptr y) {
	if (DOM_UNDEFINED(x) || DOM_UNDEFINED(y))
		return 0;
	else
		return (mpfr_less_p(IVL_LEFT(x), IVL_LEFT(y)) && 
			    mpfr_greater_p(IVL_RIGHT(x), IVL_RIGHT(y)));
}

int ivl_inside_p(ivl_srcptr x, ivl_srcptr y) {
	if (DOM_UNDEFINED(x) || DOM_UNDEFINED(y))
		return 0;
	else
		return (mpfr_lessequal_p(IVL_LEFT(x), IVL_LEFT(y)) && 
			    mpfr_greaterequal_p(IVL_RIGHT(x), IVL_RIGHT(y)));
}

int ivl_is_inside_u(ivl_srcptr ivl, unsigned long x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_ui(IVL_LEFT(ivl), x) <= 0) && 
			   (mpfr_cmp_ui(IVL_RIGHT(ivl), x) >= 0);
}

int ivl_is_inside_s(ivl_srcptr ivl, long x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_si(IVL_LEFT(ivl), x) <= 0) && 
			   (mpfr_cmp_si(IVL_RIGHT(ivl), x) >= 0);	
}

int ivl_is_inside_d(ivl_srcptr ivl, double x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_d(IVL_LEFT(ivl), x) <= 0) && 
			   (mpfr_cmp_d(IVL_RIGHT(ivl), x) >= 0);	
}

int ivl_is_inside_z(ivl_srcptr ivl, mpz_srcptr x) {		
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_z(IVL_LEFT(ivl), x) <= 0) && 
			   (mpfr_cmp_z(IVL_RIGHT(ivl), x) >= 0);	
}

int ivl_is_inside_q(ivl_srcptr ivl, mpq_srcptr x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_q(IVL_LEFT(ivl), x) <= 0) && 
			   (mpfr_cmp_q(IVL_RIGHT(ivl), x) >= 0);	
}

int ivl_is_inside_f(ivl_srcptr ivl, mpfr_srcptr x) {	
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp(IVL_LEFT(ivl), x) <= 0) && 
			   (mpfr_cmp(IVL_RIGHT(ivl), x) >= 0);
}

int ivl_is_strictly_inside_u(ivl_srcptr ivl, unsigned long x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_ui(IVL_LEFT(ivl), x) < 0) && 
			   (mpfr_cmp_ui(IVL_RIGHT(ivl), x) > 0);
}

int ivl_is_strictly_inside_s(ivl_srcptr ivl, long x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_si(IVL_LEFT(ivl), x) < 0) && 
			   (mpfr_cmp_si(IVL_RIGHT(ivl), x) > 0);	
}

int ivl_is_strictly_inside_d(ivl_srcptr ivl, double x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_d(IVL_LEFT(ivl), x) < 0) && 
			   (mpfr_cmp_d(IVL_RIGHT(ivl), x) > 0);	
}

int ivl_is_strictly_inside_z(ivl_srcptr ivl, mpz_srcptr x) {		
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_z(IVL_LEFT(ivl), x) < 0) && 
			   (mpfr_cmp_z(IVL_RIGHT(ivl), x) > 0);	
}

int ivl_is_strictly_inside_q(ivl_srcptr ivl, mpq_srcptr x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_q(IVL_LEFT(ivl), x) < 0) && 
			   (mpfr_cmp_q(IVL_RIGHT(ivl), x) > 0);	
}

int ivl_is_strictly_inside_f(ivl_srcptr ivl, mpfr_srcptr x) {	
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp(IVL_LEFT(ivl), x) < 0) && 
			   (mpfr_cmp(IVL_RIGHT(ivl), x) > 0);
}

int ivl_is_equal_u(ivl_srcptr ivl, unsigned long x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else
		return (mpfr_cmp_ui(IVL_LEFT(ivl), x) == 0) && 
			   (mpfr_cmp_ui(IVL_RIGHT(ivl), x) == 0);
}

int ivl_is_equal_s(ivl_srcptr ivl, long x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_si(IVL_LEFT(ivl), x) == 0) && 
			   (mpfr_cmp_si(IVL_RIGHT(ivl), x) == 0);	
}

int ivl_is_equal_d(ivl_srcptr ivl, double x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_d(IVL_LEFT(ivl), x) == 0) && 
			   (mpfr_cmp_d(IVL_RIGHT(ivl), x) == 0);	
}

int ivl_is_equal_z(ivl_srcptr ivl, mpz_srcptr x) {		
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_z(IVL_LEFT(ivl), x) == 0) && 
			   (mpfr_cmp_z(IVL_RIGHT(ivl), x) == 0);	
}

int ivl_is_equal_q(ivl_srcptr ivl, mpq_srcptr x) {
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp_q(IVL_LEFT(ivl), x) == 0) && 
			   (mpfr_cmp_q(IVL_RIGHT(ivl), x) == 0);	
}

int ivl_is_equal_f(ivl_srcptr ivl, mpfr_srcptr x) {	
	if (DOM_UNDEFINED(ivl))
		return 0;
	else	
		return (mpfr_cmp(IVL_LEFT(ivl), x) == 0) && 
			   (mpfr_cmp(IVL_RIGHT(ivl), x) == 0);
}
